package top.fullj.sysmon;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StatFs;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

/**
 * @author bruce.wu
 * @date 2025/6/26 13:48
 */
class AppState {

    private static final Logger LOG = LoggerFactory.getLogger(AppState.class);

    @SuppressLint("HardwareIds")
    static void grab(final Application app) {
        try {
            PackageInfo info = app.getPackageManager().getPackageInfo(app.getPackageName(), 0);
            LOG.info("packageName={}, versionName={}, versionCode={}", app.getPackageName(), info.versionName, info.versionCode);
        } catch (PackageManager.NameNotFoundException e) {
            LOG.warn("getPackageInfo failed: {}", e.getMessage());
        }
        LOG.info("{}", app.getResources().getDisplayMetrics());
        LOG.info("app.debuggable={}", (app.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
        LOG.info("app.isDebuggerConnected={}", Debug.isDebuggerConnected());

        LOG.info("Build.BOARD={}", Build.BOARD);
        LOG.info("Build.BOOTLOADER={}", Build.BOOTLOADER);
        LOG.info("Build.BRAND={}", Build.BRAND);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            LOG.info("Build.SUPPORTED_ABI={}", Arrays.toString(Build.SUPPORTED_ABIS));
        } else {
            LOG.info("Build.CPU_ABI={}", Build.CPU_ABI);
            LOG.info("Build.CPU_ABI2={}", Build.CPU_ABI2);
        }
        LOG.info("Build.DEVICE={}", Build.DEVICE);
        LOG.info("Build.DISPLAY={}", Build.DISPLAY);
        LOG.info("Build.FINGERPRINT={}", Build.FINGERPRINT);
        LOG.info("Build.HARDWARE={}", Build.HARDWARE);
        LOG.info("Build.HOST={}", Build.HOST);
        LOG.info("Build.ID={}", Build.ID);
        LOG.info("Build.MANUFACTURER={}", Build.MANUFACTURER);
        LOG.info("Build.MODEL={}", Build.MODEL);
        LOG.info("Build.PRODUCT={}", Build.PRODUCT);
        LOG.info("Build.TAGS={}", Build.TAGS);
        LOG.info("Build.TIME={}", Build.TIME);
        LOG.info("Build.TYPE={}", Build.TYPE);
        LOG.info("Build.USER={}", Build.USER);
        LOG.info("Build.SERIAL={}", Build.SERIAL);
//        LOG.info("Build.VERSION.CODENAME={}", Build.VERSION.CODENAME);
//        LOG.info("Build.VERSION.INCREMENTAL={}", Build.VERSION.INCREMENTAL);
        LOG.info("Build.VERSION.RELEASE={}", Build.VERSION.RELEASE);
        LOG.info("Build.VERSION.SDK_INT={}", Build.VERSION.SDK_INT);

        Runtime rt = Runtime.getRuntime();
        // cpu info
        LOG.info("rt.availableProcessors={}", rt.availableProcessors());
        // memory info
        LOG.info("rt.maxMemory={}", rt.maxMemory());
        LOG.info("rt.freeMemory={}", rt.freeMemory());
        LOG.info("rt.totalMemory={}", rt.totalMemory());
        // storage info
        StatFs statFs = new StatFs(Environment.getDataDirectory().getPath());
        LOG.info("storage.availableBytes={}", statFs.getAvailableBytes());

        PowerManager pm = (PowerManager) app.getSystemService(Context.POWER_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            LOG.info("power.isInteractive={}", pm.isInteractive());
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            LOG.info("power.isPowerSaveMode={}", pm.isPowerSaveMode());
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            ActivityManager am = (ActivityManager)app.getSystemService(Context.ACTIVITY_SERVICE);
            LOG.info("activity.isBackgroundRestricted={}", am.isBackgroundRestricted());
        }
    }

    static void start(final Application app) {
        app.registerActivityLifecycleCallbacks(activityLifecycleCallback);
    }

    static void stop(final Application app) {
        app.unregisterActivityLifecycleCallbacks(activityLifecycleCallback);
    }

    private static final Application.ActivityLifecycleCallbacks activityLifecycleCallback = new Application.ActivityLifecycleCallbacks() {

        private int activeActivities = 0;

        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            LOG.debug("{}::Created(state={})", activity.getClass().getName(), savedInstanceState);
        }

        @Override
        public void onActivityStarted(Activity activity) {
            activeActivities++;
            LOG.debug("{}::Started(): {}", activity.getClass().getName(), activeActivities);
        }

        @Override
        public void onActivityResumed(Activity activity) {
            activeActivities--;
            LOG.debug("{}::Resumed(): {}", activity.getClass().getName(), activeActivities);
        }

        @Override
        public void onActivityPaused(Activity activity) {
            LOG.debug("{}::Paused()", activity.getClass().getName());
        }

        @Override
        public void onActivityStopped(Activity activity) {
            LOG.debug("{}::Stopped()", activity.getClass().getName());
        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            LOG.debug("{}::SaveInstanceState((state={})", activity.getClass().getName(), outState);
        }

        @Override
        public void onActivityDestroyed(Activity activity) {
            LOG.debug("{}::Destroyed()", activity.getClass().getName());
        }
    };

}
